(function () {
  window.crossLocalStorage = {
    consumerOrigins: [],
    // 设置允许消费我的LocalStorage的域名清单
    setConsumerOrigins(...origins) {
      this.consumerOrigins = origins.map((v) => {
        return v.endsWith('/') ? v.slice(0, v.length - 1) : v;
      });
    },

    providerOrigins: [],
    providerOriginIframeMap: {},
    // 设置给我供应LocalStorage的域名清单
    setProviderOrigins(...origins) {
      return new Promise((resolve) => {
        this.providerOrigins = origins.map((v) => {
          return v.endsWith('/') ? v.slice(0, v.length - 1) : v;
        });

        this.providerOrigins.forEach((v) => {
          const iframe = document.createElement('iframe');
          iframe.src =
            v + '/cross-local-storage.html?now=' + Math.random().toString().slice(2);
          iframe.style =
            'position: absolute; left: -999px; width: 5px; height: 5px;';

          document.body.appendChild(iframe);

          this.providerOriginIframeMap[v] = iframe;

          iframe.addEventListener('load', () => {
            iframe.__loaded__ = true;
            if (
              Object.values(this.providerOriginIframeMap).every(
                (v2) => v2.__loaded__,
              )
            ) {
              resolve(this);
            }
          });
        });
      });
    },

    getItemResolveFunctionMap: {},
    getItem(origin, key) {
      origin = origin.endsWith('/')
        ? origin.slice(0, origin.length - 1)
        : origin;
      return new Promise((resolve, reject) => {
        const getItemResolveFunctionKey = Math.random().toString().slice(2, 18);
        this.getItemResolveFunctionMap[getItemResolveFunctionKey] = (value) => {
          resolve(value);
          delete this.getItemResolveFunctionMap[getItemResolveFunctionKey];
        };

        const tempFn = () => {
          if (!this.providerOriginIframeMap[origin].__loaded__) {
            setTimeout(tempFn, 10);
          } else {
            this.providerOriginIframeMap[origin].contentWindow.postMessage(
              { key, isCrossLocalStorage: true, getItemResolveFunctionKey },
              origin,
            );
          }
        };
        setTimeout(tempFn, 10);

        setTimeout(() => {
          reject('getItem Timeout!!!');
          delete this.getItemResolveFunctionMap[getItemResolveFunctionKey];
        }, 2000);
      });
    },
  };

  window.addEventListener(
    'message',
    function (e) {
      if (!e.data || !e.data.isCrossLocalStorage) return;

      if (e.data.key && e.data.getItemResolveFunctionKey) {
        if (!window.crossLocalStorage.consumerOrigins.includes(e.origin))
          return;

        e.source.postMessage(
          {
            value: window.localStorage.getItem(e.data.key),
            isCrossLocalStorage: true,
            getItemResolveFunctionKey: e.data.getItemResolveFunctionKey,
          },
          e.origin,
        );
      }

      if (e.data.value !== undefined && e.data.getItemResolveFunctionKey) {
        window.crossLocalStorage.getItemResolveFunctionMap[
          e.data.getItemResolveFunctionKey
        ](e.data.value);
      }
    },
    false,
  );
})();
